# -*- coding: utf-8 -*-
from abc import ABC
import csv
import pickle

from app.models.dao import db2vectors
from app.configs import kj236_pool
from app.models.model import TrackModel, PositionModel, MineModel
from app.models import db_session
from app.models.dao import clear_all
from app.configs import root_path
from app.views import CommonHandler
from app.tools.utils import distance, foot_point, point_in_box, THRESHOLD
from app.tools.utils import csv_float, csv_int


def csv2mine(file):
    session = db_session()

    with open(file, encoding="utf-8") as f:
        for c in csv.reader(f, skipinitialspace=True):
            mine = MineModel()
            # mine.id = int(c[0])
            mine.mine_code = c[1]
            mine.mine_name = c[2]
            mine.mine_pinyin = c[3]
            mine.mine_pinyin_first = c[4]
            mine.mine_yield = csv_float(c[5])
            mine.mine_yield_check = csv_float(c[6])
            mine.check_date = None
            mine.provice = c[8]
            mine.city = c[9]
            mine.county = c[10]
            mine.township = c[11]
            mine.address = c[12]
            mine.provincial_office = c[13]
            mine.suboffice_name = c[14]
            mine.group_name = c[15]
            mine.coalseam_num = csv_float(c[16])
            mine.mine_area = csv_float(c[17])
            mine.build_time = None
            mine.longitude = csv_float(c[19])
            mine.latitude = csv_float(c[20])
            mine.description = c[21]
            mine.mine_status = csv_int(c[22])
            mine.gas_level = csv_int(c[23])
            mine.water_condition = csv_int(c[24])
            mine.rock_burst_tendency = csv_int(c[25])
            mine.roof_hazard_type = csv_int(c[26])
            mine.coal_fire_tendency = csv_int(c[27])
            mine.dust_explosion_danger = csv_int(c[28])
            session.add(mine)

    session.commit()
    session.close()


def delete_positions_and_tracks(meta_id):
    session = db_session()
    t, p = TrackModel, PositionModel
    values = session.query(t).filter(t.meta_id == meta_id).all()
    for item in values:
        session.delete(item)

    values = session.query(p).filter(p.meta_id == meta_id).all()
    for item in values:
        session.delete(item)

    session.commit()
    session.close()


def person(person_id, geojson):
    session = db_session()

    query_script = "SELECT * from m_geojson WHERE id='%s'" % geojson
    fetchall = kj236_pool.select(query_script)
    person_track, person_json = [], fetchall[0][2]
    for feature in person_json['features']:
        track = TrackModel(feature["geometry"]["coordinates"], person_id)
        track.dxftype = "person"
        session.add(track)
    session.commit()

    tracks = db2vectors(TrackModel, person_id)
    fetchall = kj236_pool.select("SELECT * from m_position")
    for item in fetchall:
        if item[3] is None and item[4] is None:
            continue

        pt = [item[3], item[4]]
        for track in tracks:
            if track['type'] != 'person':
                continue

            l, r = track['left'], track['right']
            b, t = track['bottom'], track['top']
            if point_in_box(pt, l, r, t, b) is False:
                continue

            points = track['points']
            for i in range(0, len(points) - 1):
                ls, le, fp = points[i], points[i + 1], [0, 0]
                if foot_point(pt, ls, le, fp):
                    if distance(pt[0], pt[1], fp[0], fp[1]) < THRESHOLD:
                        points.insert(i + 1, pt)
                        position = PositionModel(pt, person_id)
                        position.insert_id = str(track['id'])
                        position.dxftype = 'person'
                        position.node_id = item[1]
                        session.add(position)
                        ts = session.query(TrackModel).filter(TrackModel.id == track['id']).all()
                        for t in ts:
                            t.points = pickle.dumps(points)
                        session.commit()
                        break
    session.close()


def vehicle(vehicle_id, geojson):
    session = db_session()

    query_script = "SELECT * from m_geojson WHERE id='%s'" % geojson
    fetchall = kj236_pool.select(query_script)
    vehicle_tracks, vehicle_json = [], fetchall[0][2]
    for feature in vehicle_json['features']:
        track = TrackModel(feature["geometry"]["coordinates"], vehicle_id)
        track.dxftype = "vehicle"
        session.add(track)
    session.commit()

    tracks = db2vectors(TrackModel, vehicle_id)
    fetchall = kj236_pool.select("SELECT * from m_position_vehicle")
    for item in fetchall:
        if item[3] is None and item[4] is None:
            continue

        pt = [item[3], item[4]]
        for track in tracks:
            if track['type'] != 'vehicle':
                continue

            l, r = track['left'], track['right']
            b, t = track['bottom'], track['top']
            if point_in_box(pt, l, r, t, b) is False:
                continue

            points = track['points']
            for i in range(0, len(points) - 1):
                ls, le, fp = points[i], points[i + 1], [0, 0]
                if foot_point(pt, ls, le, fp):
                    if distance(pt[0], pt[1], fp[0], fp[1]) < THRESHOLD:
                        points.insert(i + 1, pt)
                        position = PositionModel(pt, vehicle_id)
                        position.insert_id = str(track['id'])
                        position.dxftype = 'vehicle'
                        position.node_id = item[1]
                        session.add(position)
                        ts = session.query(TrackModel).filter(TrackModel.id == track['id']).all()
                        for t in ts:
                            t.points = pickle.dumps(points)
                        session.commit()
                        break
    session.close()


class InitHandler(CommonHandler, ABC):
    async def get(self):
        person_id = self.get_argument("person_id", None)
        vehicle_id = self.get_argument("vehicle_id", None)
        geojson = self.get_argument("geojson", None)
        resp = "Init csv!"

        if person_id is None and vehicle_id is None:
            clear_all()
            csv2mine(root_path + 'mine.csv')

        if person_id is not None and geojson is not None:
            delete_positions_and_tracks(person_id)
            person(person_id, geojson)
            resp = "Init person geojson!"

        if vehicle_id is not None and geojson is not None:
            delete_positions_and_tracks(vehicle_id)
            vehicle(vehicle_id, geojson)
            resp = "Init vehicle geojson!"

        await self.response(data=resp)
